//
//  XDAFNetworking.m
//  kabu
//
//  Created by XiangDongMBP on 2017/1/17.
//  Copyright © 2017年 East. All rights reserved.
//

#import "XDAFNetworking.h"
#import "GlobalHeader.h"

@interface XDAFNetworking ()

//@property ()
@property (nonatomic, strong) AFHTTPSessionManager *manager;

@end

/**
 *  是否开启https SSL 验证
 *  YES为开启，NO为关闭
 */
BOOL const kOpenHttpsSSL = NO;
/**
 *  SSL 证书名称，仅支持cer格式。“app.bishe.com.cer”,则填“app.bishe.com”
 */
NSString * const kCertificate = @"and";
/**
 *  BaseUrlString
 */

#if KABU_DEVELOPMENT_MODE
NSString * const kBaseUrlString = @"https://appceshi.tokabu.com";
#else
NSString * const kBaseUrlString = @"https://app.tokabu.com";
#endif

// 服务器返回的错误代码
static NSInteger const kTokenInvalid = 444;     //!< 鉴权失败，需要重新登录
static NSInteger const kUserNotLogin = 445;     //!< 没有登录，需要登录

@implementation XDAFNetworking

+ (instancetype)sharedInstance {
    static XDAFNetworking * sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:kBaseUrlString]];
//        if (kOpenHttpsSSL) {
//            _manager.securityPolicy = [self customSecurityPolicy];
//        }
    }
    return self;
}

- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(id)parameters
                     progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                      success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                      failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {
    self.manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    // 统一处理错误的地方
    void (^successHandle)(NSURLSessionDataTask * _Nonnull, id _Nullable) = ^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(task, responseObject);
        }
        if ([responseObject[@"err_code"] integerValue] == kTokenInvalid
            || [responseObject[@"err_code"] integerValue] == kUserNotLogin) {
            [[NSNotificationCenter defaultCenter] postNotificationName:KABGlobalNotiUserTokenInvalid object:nil];
        }
    };
    return [self.manager GET:URLString parameters:parameters progress:downloadProgress success:successHandle failure:failure];
}

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(id)parameters
                      progress:(void (^)(NSProgress * _Nonnull))uploadProgress
                       success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                       failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {
    self.manager.requestSerializer = [AFJSONRequestSerializer serializer];
    // 统一处理错误的地方
    void (^successHandle)(NSURLSessionDataTask * _Nonnull, id _Nullable) = ^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(task, responseObject);
        }
        if ([responseObject[@"err_code"] integerValue] == kTokenInvalid
            || [responseObject[@"err_code"] integerValue] == kUserNotLogin) {
            [[NSNotificationCenter defaultCenter] postNotificationName:KABGlobalNotiUserTokenInvalid object:nil];
        }
    };
    return [self.manager POST:URLString parameters:parameters progress:uploadProgress success:successHandle failure:failure];
}

- (NSURLSessionDataTask *)PUT:(NSString *)URLString
                   parameters:(id)parameters
                      success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                      failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {
    self.manager.requestSerializer = [AFJSONRequestSerializer serializer];
    // 统一处理错误的地方
    void (^successHandle)(NSURLSessionDataTask * _Nonnull, id _Nullable) = ^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(task, responseObject);
        }
        if ([responseObject[@"err_code"] integerValue] == kTokenInvalid
            || [responseObject[@"err_code"] integerValue] == kUserNotLogin) {
            [[NSNotificationCenter defaultCenter] postNotificationName:KABGlobalNotiUserTokenInvalid object:nil];
        }
    };
    return [self.manager PUT:URLString parameters:parameters success:successHandle failure:failure];
}

- (NSURLSessionDataTask *)DELETE:(NSString *)URLString
                      parameters:(id)parameters
                         success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                         failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {
    self.manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    // 统一处理错误的地方
    void (^successHandle)(NSURLSessionDataTask * _Nonnull, id _Nullable) = ^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (success) {
            success(task, responseObject);
        }
        if ([responseObject[@"err_code"] integerValue] == kTokenInvalid
            || [responseObject[@"err_code"] integerValue] == kUserNotLogin) {
            [[NSNotificationCenter defaultCenter] postNotificationName:KABGlobalNotiUserTokenInvalid object:nil];
        }
    };
    return [self.manager DELETE:URLString parameters:parameters success:successHandle failure:failure];
}



#pragma mark - SSL证书相关
// 项目源码自带cer证书访问https
- (AFSecurityPolicy *)customSecurityPolicy {
    // /先导入证书
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:kCertificate ofType:@"cer"];//证书的路径
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
    // AFSSLPinningModeCertificate 使用证书验证模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    
    // allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO
    // 如果是需要验证自建证书，需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;
    
    //validatesDomainName 是否需要验证域名，默认为YES；
    //假如证书的域名与你请求的域名不一致，需把该项设置为NO；如设成NO的话，即服务器使用其他可信任机构颁发的证书，也可以建立连接，这个非常危险，建议打开。
    //置为NO，主要用于这种情况：客户端请求的是子域名，而证书上的是另外一个域名。因为SSL证书上的域名是独立的，假如证书上注册的域名是www.google.com，那么mail.google.com是无法验证通过的；当然，有钱可以注册通配符的域名*.google.com，但这个还是比较贵的。
    //如置为NO，建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;
    
    securityPolicy.pinnedCertificates = [NSSet setWithObject:certData];
    
    return securityPolicy;
}

// 这个可以不使用证书就可以访问https
- (AFSecurityPolicy *)customDefaultPolicy {
    AFSecurityPolicy * sslDefaultPolicy = [AFSecurityPolicy defaultPolicy];
    sslDefaultPolicy.allowInvalidCertificates = YES;
    sslDefaultPolicy.validatesDomainName = NO;
    return sslDefaultPolicy;
}

@end
